<template>
    <div ref="chartRef" style="width: 100%; height: 500px;"></div>
</template>

<script setup>
import { onMounted, onBeforeUnmount, ref } from 'vue';
import * as echarts from 'echarts';
import 'echarts-gl';

const chartRef = ref(null);
let Chart_pie = null;

// 数据
const pieData = [
  { name: '类别1', value: 335, itemStyle: { color: '#2B8EF3' } },
  { name: '类别2', value: 310, itemStyle: { color: '#9CBECF' } },
  { name: '类别3', value: 234, itemStyle: { color: '#2C49B8' } },
  { name: '类别4', value: 135, itemStyle: { color: '#3DBCBE' } }
];

// 获取 3D 环形图配置
const getPie3D = (pieData, internalDiameterRatio, height) => {
  const series = [];
  let sumValue = 0;
  let startValue = 0;
  let endValue = 0;
  const legendData = [];
  const k = typeof internalDiameterRatio !== 'undefined' ? (1 - internalDiameterRatio) / (1 + internalDiameterRatio) : 1 / 3;

  pieData.forEach((item, index) => {
    sumValue += item.value;
    const seriesItem = {
      name: typeof item.name === 'undefined' ? `series${index}` : item.name,
      type: 'surface',
      parametric: true,
      wireframe: {
        show: false
      },
      pieData: item,
      pieStatus: {
        selected: false,
        hovered: false,
        k: k
      }
    };

    if (typeof item.itemStyle !== 'undefined') {
      seriesItem.itemStyle = item.itemStyle;
    }

    series.push(seriesItem);
  });

  series.forEach((item, index) => {
    endValue = startValue + item.pieData.value;
    item.pieData.startRatio = startValue / sumValue;
    item.pieData.endRatio = endValue / sumValue;
    item.parametricEquation = getParametricEquation(item.pieData.startRatio, item.pieData.endRatio, false, false, k, height);
    startValue = endValue;
    legendData.push(item.name);
  });

  return {
    legend: {
      data: legendData,
      bottom: 0,
      textStyle: {
        color: 'white',
        fontFamily: 'Source Han Sans CN',
        fontSize: 14
      }
    },
    xAxis3D: {
      min: -1,
      max: 1
    },
    yAxis3D: {
      min: -1,
      max: 1
    },
    zAxis3D: {
      min: -2,
      max: 2
    },
    grid3D: {
      show: false,
      boxHeight: 3,
      viewControl: {
        alpha: 45,
        distance: 170,
        rotateSensitivity: 0,
        zoomSensitivity: 0,
        panSensitivity: 0,
        autoRotate: false
      },
      postEffect: {
        enable: true,
        bloom: {
          enable: true,
          bloomIntensity: 1
        },
        SSAO: {
          enable: true,
          quality: 'medium',
          radius: 2
        }
      }
    },
    series: series
  };
};

// 获取参数方程
const getParametricEquation = (startRatio, endRatio, isSelected, isHovered, k, height) => {
  const midRatio = (startRatio + endRatio) / 2;
  const startRadian = startRatio * Math.PI * 2;
  const endRadian = endRatio * Math.PI * 2;
  const midRadian = midRatio * Math.PI * 2;
  k = typeof k !== 'undefined' ? k : 1 / 3;
  const offsetX = isSelected ? Math.cos(midRadian) * 0.1 : 0;
  const offsetY = isSelected ? Math.sin(midRadian) * 0.1 : 0;
  const hoverRate = isHovered ? 1.05 : 1;

  return {
    u: {
      min: -Math.PI,
      max: Math.PI * 3,
      step: Math.PI / 32
    },
    v: {
      min: 0,
      max: Math.PI * 2,
      step: Math.PI / 20
    },
    x: (u, v) => {
      if (u < startRadian) {
        return offsetX + Math.cos(startRadian) * (1 + Math.cos(v) * k) * hoverRate;
      }
      if (u > endRadian) {
        return offsetX + Math.cos(endRadian) * (1 + Math.cos(v) * k) * hoverRate;
      }
      return offsetX + Math.cos(u) * (1 + Math.cos(v) * k) * hoverRate;
    },
    y: (u, v) => {
      if (u < startRadian) {
        return offsetY + Math.sin(startRadian) * (1 + Math.cos(v) * k) * hoverRate;
      }
      if (u > endRadian) {
        return offsetY + Math.sin(endRadian) * (1 + Math.cos(v) * k) * hoverRate;
      }
      return offsetY + Math.sin(u) * (1 + Math.cos(v) * k) * hoverRate;
    },
    z: (u, v) => {
      if (u < -Math.PI * 0.5) {
        return Math.sin(u);
      }
      if (u > Math.PI * 2.5) {
        return Math.sin(u);
      }
      return Math.sin(v) > 0 ? 1 * height : -1;
    }
  };
};

// 初始化图表
onMounted(() => {
  Chart_pie = echarts.init(chartRef.value);
  Chart_pie.setOption(getPie3D(pieData, 0.75, 10));
});

// 销毁图表
onBeforeUnmount(() => {
  if (Chart_pie) {
    Chart_pie.dispose();
    Chart_pie = null;
  }
});
</script>

<style lang="scss" scoped>
</style>